package org.common.utils;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Calendar;
import java.util.Date;

public class DateUtils {
    private static DateTimeFormatter formatter;
    private static SimpleDateFormat dateFormat;

    public enum TimeEnum {
        DEFAULT_DATE("yyyy-MM-dd"),
        DEFAULT_OBLIQUE_DATE("yyyy/MM/dd"),
        HOUR_MINUTE_SECOND_DATE("HH:mm:ss"),
        DEFAULT_ALL_DATE("yyyy-MM-dd HH:mm:ss"),
        DEFAULT_HOUR_MINUTE_DATE("yyyy-MM-dd HH:mm");

        private String desc;

        TimeEnum(String desc) {
            this.desc = desc;
        }

        public String getDesc() {
            return desc;
        }

        public void setDesc(String desc) {
            this.desc = desc;
        }
    }


    private static DateTimeFormatter getDateTimeFormatter(final String dateFormat) {
        return DateUtils.formatter = DateTimeFormatter.ofPattern(dateFormat);
    }
    
    private static SimpleDateFormat getSimpleDateFormat(final String dateFormat){
        return DateUtils.dateFormat = new SimpleDateFormat(dateFormat);
    }

    public static String getNowTime() {
        return dateToString(TimeEnum.DEFAULT_DATE);
    }

    public static String getLongNowTime() {
        return dateToString(TimeEnum.DEFAULT_ALL_DATE);
    }

    public static String dateToString(final TimeEnum timeEnum) {
        switch (timeEnum) {
            case DEFAULT_DATE: {
                return LocalDate.now().format(getDateTimeFormatter(TimeEnum.DEFAULT_DATE.getDesc()));
            }
            case DEFAULT_OBLIQUE_DATE: {
                return LocalDate.now().format(getDateTimeFormatter(TimeEnum.DEFAULT_OBLIQUE_DATE.getDesc()));
            }
            case HOUR_MINUTE_SECOND_DATE: {
                return LocalDate.now().format(getDateTimeFormatter(TimeEnum.HOUR_MINUTE_SECOND_DATE.getDesc()));
            }
            case DEFAULT_ALL_DATE: {
                return LocalDate.now().format(getDateTimeFormatter(TimeEnum.DEFAULT_ALL_DATE.getDesc()));
            }
            case DEFAULT_HOUR_MINUTE_DATE: {
                return LocalDate.now().format(getDateTimeFormatter(TimeEnum.DEFAULT_HOUR_MINUTE_DATE.getDesc()));
            }
            default: {
                return "";
            }
        }
    }

    public static String formatDate(final String dateFormat, final Date date) {
        return getSimpleDateFormat(dateFormat).format(date);
    }

    public static boolean isTimeRange(final String beginDateString) {
        Date beginDate = null;
        try {
            beginDate =  getSimpleDateFormat(TimeEnum.DEFAULT_ALL_DATE.getDesc()).parse(beginDateString);
        } catch (ParseException e) {
            e.printStackTrace();
        }
//        beginDate = LocalDateTime.parse(TimeEnum.DEFAULT_ALL_DATE.getDesc(), getDateTimeFormatter(TimeEnum.DEFAULT_ALL_DATE.getDesc()));
//        ZoneId zoneId = ZoneId.systemDefault();
//        ZonedDateTime zonedDateTime = beginDate.atZone(zoneId);
        return isTimeRange(beginDate, 2);
    }

    public static boolean isTimeRange(final Date beginDate, final int deviation) {
        System.out.println(dateToString(TimeEnum.DEFAULT_ALL_DATE));
        final long diff = new Date().getTime() - beginDate.getTime();
        return diff % 86400000L / 3600000L <= deviation;
    }

    public static DateTime offset(final Date date, final DateField dateField, final int offset) {
        final Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.add(dateField.getValue(), offset);
        return new DateTime(cal.getTime());
    }

    /**
     * 获取本月第一天
     */
    public static String getFirstDayToMonth() {
        LocalDate localDate = LocalDate.now();
        return String.valueOf(LocalDate.of(localDate.getYear(), localDate.getMonth(), 1));
    }

    /**
     * 获取本月最后一天
     */
    public static String getLastDayToMonth() {
        return String.valueOf(LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()));
    }

    /**
     * 获取本年最后一天
     */
    public static String getLastDayToYear() {
        return String.valueOf(LocalDate.now().with(TemporalAdjusters.lastDayOfYear()));
    }

    public static void main(final String[] args) {
//        System.out.println(isTimeRange("2018-4-29 14:56:09"));
//        System.out.println(DateUtils.getLastDayToYear());
        System.out.println(LocalDateTime.now().minusDays(1));
    }

    static {
        DateUtils.dateFormat = null;
    }
}
